package 滑动窗口;

import com.alibaba.fastjson.JSON;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.TreeMap;

public class No239滑动窗口最大值 {

    /**
     * 给你一个整数数组 nums，有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。
     * 你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
     * 返回滑动窗口中的最大值。
     *
     * 示例 1：
     * 输入：nums = [1,3,-1,-3,5,3,6,7], k = 3
     * 输出：[3,3,5,5,6,7]
     * 解释：
     * 滑动窗口的位置                最大值
     * ---------------               -----
     * [1  3  -1] -3  5  3  6  7       3
     *  1 [3  -1  -3] 5  3  6  7       3
     *  1  3 [-1  -3  5] 3  6  7       5
     *  1  3  -1 [-3  5  3] 6  7       5
     *  1  3  -1  -3 [5  3  6] 7       6
     *  1  3  -1  -3  5 [3  6  7]      7
     * 示例 2：
     * 输入：nums = [1], k = 1
     * 输出：[1]
     * 示例 3：
     * 输入：nums = [1,-1], k = 1
     * 输出：[1,-1]
     * 示例 4：
     * 输入：nums = [9,11], k = 2
     * 输出：[11]
     * 示例 5：
     * 输入：nums = [4,-2], k = 2
     * 输出：[4]
     *  
     * 提示：
     * 1 <= nums.length <= 105
     * -104 <= nums[i] <= 104
     * 1 <= k <= nums.length
     */

    public int[] maxSlidingWindow(int[] nums, int k) {

        int[] result=new int[nums.length-k+1];

        /**
         * 可用数据结构: 红黑树,堆,Queue
         * Queue怎么用? 用笔画画即可
         */
        int index=0;
        int left=0;
        int right=0;
        Deque<Integer> queue=new ArrayDeque<>(k);

        while (right<nums.length){

            //滑动窗口的最大值

            //不断的吐出比当前元素小的值
            while (!queue.isEmpty()&&queue.peekLast()<nums[right]){
                queue.pollLast();
            }

            queue.addLast(nums[right]);

            right++;

            if(right-left>k){
                //开始吐出
                Integer num = queue.peekFirst();
                if(num==nums[left]){
                    queue.pollFirst();
                }
                left++;
            }

            if(right-left==k){
                result[index++]=queue.peekFirst();
            }

        }

        return result;
    }

    public static void main(String[] args) {
        No239滑动窗口最大值 n=new No239滑动窗口最大值();
        int[] arr={1,3,-1,-3,5,3,6,7};
        int[] result = n.maxSlidingWindow(arr, 3);
        System.out.println(JSON.toJSONString(result));
    }

}
